package com.cdxy.service.impl;

import com.cdxy.dmr.dataObject.AxUserDO;
import com.cdxy.dmr.dataObject.AxUserProfileDO;
import com.cdxy.dmr.repository.AxUserProfileRepository;
import com.cdxy.dmr.repository.AxUserRepository;
import com.cdxy.enums.*;
import com.cdxy.model.dto.base.exception.BusinessException;
import com.cdxy.model.dto.req.RegsEmailCodeReq;
import com.cdxy.model.dto.req.RegsMobileCodeReq;
import com.cdxy.service.IEmailService;
import com.cdxy.service.IRegsService;
import com.cdxy.service.ISmsService;
import com.cdxy.util.AvatarUtil;
import com.cdxy.util.NicknameUtil;
import com.cdxy.util.UidUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.time.LocalDate;

/**
 * @Author: tangy
 * @Date: 2020/3/17 10:44
 */
@Service
@Slf4j
public class RegsServiceImpl implements IRegsService {

    @Autowired
    private AxUserRepository axUserRepository;

    @Autowired
    private AxUserProfileRepository axUserProfileRepository;

    @Autowired
    private ISmsService smsService;

    @Autowired
    private IEmailService emailService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public void regsByMobileCode(RegsMobileCodeReq regsMobileCodeReq) {
        String phone = regsMobileCodeReq.getPhone();
        String code = regsMobileCodeReq.getCode();
        String password = regsMobileCodeReq.getPassword();

        AxUserDO axUserDO = axUserRepository.getByMobile(phone);
        if (axUserDO != null) {
            throw new BusinessException(BizErrorEnum.REGS_ACCOUNT_EXIST_REPEAT);
        }

        smsService.verifySms(KaptchaEnum.BusinessCode.REGS_SMS, phone, code);

        // 手机注册
        axUserDO = new AxUserDO();
        axUserDO.setMobile(phone);
        axUserDO.setRole(UserRoleEnum.NORMAL.name());
        axUserDO.setPassword(password);
        axUserDO.setStatus(true);

        AxUserDO finalAxUserDO = axUserDO;
        transactionTemplate.execute(status -> {
            try {
                axUserRepository.save(finalAxUserDO);
                Integer axUid = finalAxUserDO.getAxUid();

                AxUserProfileDO axUserProfileDO = new AxUserProfileDO();
                axUserProfileDO.setSex(UserSexEnum.UNKNOWN.getCode());
                axUserProfileDO.setNickname(NicknameUtil.buildDefaultNickName(UserTypeEnum.MOBILE, UidUtil.generateCodeByAxUid(axUid)));
                axUserProfileDO.setAvatar(AvatarUtil.buildDefaultAvatar(axUid));
                axUserProfileDO.setBirthDay(LocalDate.now());
                axUserProfileDO.setAxUid(axUid);
                axUserProfileRepository.save(axUserProfileDO);
                return null;
            } catch (Exception e) {
                status.setRollbackOnly();
                log.error("手机验证码注册失败,{}", phone);
                throw e;
            }
        });
    }

    @Override
    public void regsByEmailCode(RegsEmailCodeReq regsEmailCodeReq) {
        String email = regsEmailCodeReq.getEmail();
        String code = regsEmailCodeReq.getCode();
        String password = regsEmailCodeReq.getPassword();

        AxUserDO axUserDO = axUserRepository.getByEmail(email);
        if (axUserDO != null) {
            throw new BusinessException(BizErrorEnum.REGS_ACCOUNT_EXIST_REPEAT);
        }

        emailService.verifyEmail(KaptchaEnum.BusinessCode.REGS_SMS, email, code);

        // 邮箱注册
        axUserDO = new AxUserDO();
        axUserDO.setEmail(email);
        axUserDO.setRole(UserRoleEnum.NORMAL.name());
        axUserDO.setPassword(password);
        axUserDO.setStatus(true);

        AxUserDO finalAxUserDO = axUserDO;
        transactionTemplate.execute(status -> {
            try {
                axUserRepository.save(finalAxUserDO);

                Integer axUid = finalAxUserDO.getAxUid();
                AxUserProfileDO axUserProfileDO = new AxUserProfileDO();
                axUserProfileDO.setAxUid(axUid);
                axUserProfileDO.setSex(UserSexEnum.UNKNOWN.getCode());
                axUserProfileDO.setNickname(NicknameUtil.buildDefaultNickName(UserTypeEnum.EMAIL, UidUtil.generateCodeByAxUid(axUid)));
                axUserProfileDO.setAvatar(AvatarUtil.buildDefaultAvatar(axUid));
                axUserProfileDO.setBirthDay(LocalDate.now());

                axUserProfileRepository.save(axUserProfileDO);
                return null;
            } catch (Exception e) {
                status.setRollbackOnly();
                log.error("邮箱注册失败,{}", email);
                throw e;
            }
        });
    }
}
